Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial specification of JDQL #520

Merged
merged 22 commits into from
Mar 17, 2024
Merged

Initial specification of JDQL #520

merged 22 commits into from
Mar 17, 2024

Conversation

gavinking
Copy link
Contributor

@gavinking gavinking commented Mar 5, 2024

Pushing this to collect feedback/suggestions in a disciplined way. Plenty of things still to clarify, of course.

See #458.

@gavinking gavinking changed the title Draft specification of JDQL Proposed draft specification of JDQL Mar 5, 2024
Copy link
Contributor

@njr-11 njr-11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great - it amounts to a very useful subset of JPQL which at least at first glances looks like it will cover everything you can do with Query by Method Name, plus some additional capability beyond that, which is good because it gives advanced users the ability to do some more powerful things with queries. I didn't review in depth yet, especially with regard to double checking that everything is a subset of JPQL (and I hope we can rely on Jakarta Persistence spec community for that as well). I included a few initial comments, but this is definitely headed in the right direction and it's exciting how far along it already is!

spec/src/antlr/JDQL.g4 Show resolved Hide resolved
spec/src/antlr/JDQL.g4 Show resolved Hide resolved
spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved
@gavinking
Copy link
Contributor Author

Looks like I need to rebase this.

@gavinking
Copy link
Contributor Author

I just reviewed the existing comments, and made a couple of very minor changes. I believe that all existing feedback has now been addressed.

@gavinking gavinking force-pushed the jdql branch 2 times, most recently from a355847 to 547de83 Compare March 12, 2024 11:04
@gavinking gavinking changed the title Proposed draft specification of JDQL Initial specification of JDQL Mar 12, 2024
(it's already defined by the grammar)
Copy link
Contributor

@njr-11 njr-11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. I didn't find much new because a lot of it we have reviewed already. I added a few minor comments/typo fixes. Feel free to ignore the suggestions that aim to avoid hard coding the Jakarta Persistence specification version number and section numbers if you don't like that idea.

spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved

In the JDQL grammar, identifiers are labelled with the `IDENTIFIER` token type.

The following identifiers are _keywords_: `select`, `update`, `set`, `delete`, `from`, `where`, `order`, `by`, `asc`, `desc`, `not`, `and`, `or`, `between`, `like`, `in`, `null`, `local`, `true`, `false`. In addition, every reserved identifier listed in section 4.4.1 of the Jakarta Persistence specification version 3.2 is also considered a reserved identifier. Keywords and other reserved identifiers are case-insensitive: `null`, `Null`, and `NULL` are three ways to write the same keyword.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following would make it so that we don't need to update the reference to Jakarta Persistence specification version number with each new release. The tradeoff is that it is not as explicit.

Suggested change
The following identifiers are _keywords_: `select`, `update`, `set`, `delete`, `from`, `where`, `order`, `by`, `asc`, `desc`, `not`, `and`, `or`, `between`, `like`, `in`, `null`, `local`, `true`, `false`. In addition, every reserved identifier listed in section 4.4.1 of the Jakarta Persistence specification version 3.2 is also considered a reserved identifier. Keywords and other reserved identifiers are case-insensitive: `null`, `Null`, and `NULL` are three ways to write the same keyword.
The following identifiers are _keywords_: `select`, `update`, `set`, `delete`, `from`, `where`, `order`, `by`, `asc`, `desc`, `not`, `and`, `or`, `between`, `like`, `in`, `null`, `local`, `true`, `false`. In addition, every reserved identifier listed in the "Identifiers" section of the Jakarta Persistence specification is also considered a reserved identifier. Keywords and other reserved identifiers are case-insensitive: `null`, `Null`, and `NULL` are three ways to write the same keyword.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmmmm. Hrrrrm. The assumption here is that section numbers are much more likely to change than section titles, which is probably true ... but I dunno, a single-word doesn't seem like a wonderful sort of reference. Not sure if this is a good idea or not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the section title could also change and we would be similarly broken. Neither of the options are ideal. I wasn't sure if the suggested change would be an improvement and decided to identify the possibility of it. If it isn't an improvement, we can leave the references to the numbers and mark this conversation resolved.

spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved

If the JDQL implementation does not support a one of the standard functions explicitly listed above, it must throw `UnsupportedOperationException` when the function name occurs in a query. Alternatively, the Jakarta Data provider is permitted to reject a repository method declaration at compilation time if its `@Query` annotation uses an unsupported function.

NOTE: On the other hand, an implementation of JDQL might provide additional built-in functions, and might even allow invocation of user-defined functions. Section 4.7 of the Jakarta Persistence specification defines a set of functions that all JPQL implementations are required to provide, including `concat`, `substring`, `trim`, `locate`, `ceiling`, `floor`, `exp`, `ln`, `mod`, `power`, `round`, `sign`, `sqrt`, `cast`, `extract`, `coalesce`, and `nullif`. JDQL implementations are encouraged to support any of these functions which are reasonably implementable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following could be done to remain correct if the sections are renumbered in Jakarta Persistence.

Suggested change
NOTE: On the other hand, an implementation of JDQL might provide additional built-in functions, and might even allow invocation of user-defined functions. Section 4.7 of the Jakarta Persistence specification defines a set of functions that all JPQL implementations are required to provide, including `concat`, `substring`, `trim`, `locate`, `ceiling`, `floor`, `exp`, `ln`, `mod`, `power`, `round`, `sign`, `sqrt`, `cast`, `extract`, `coalesce`, and `nullif`. JDQL implementations are encouraged to support any of these functions which are reasonably implementable.
NOTE: On the other hand, an implementation of JDQL might provide additional built-in functions, and might even allow invocation of user-defined functions. The section of the Jakarta Persistence specification titled "Scalar Expressions" defines a set of functions that all JPQL implementations are required to provide, including `concat`, `substring`, `trim`, `locate`, `ceiling`, `floor`, `exp`, `ln`, `mod`, `power`, `round`, `sign`, `sqrt`, `cast`, `extract`, `coalesce`, and `nullif`. JDQL implementations are encouraged to support any of these functions which are reasonably implementable.


==== Numeric types and numeric type promotion

The type assigned to an operator expression depends on the types of its operand expression, which need not be identical. The rules for numeric promotion are given in section 4.7 of the Jakarta Persistence specification version 3.2:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The type assigned to an operator expression depends on the types of its operand expression, which need not be identical. The rules for numeric promotion are given in section 4.7 of the Jakarta Persistence specification version 3.2:
The type assigned to an operator expression depends on the types of its operand expression, which need not be identical. The rules for numeric promotion are given in the "Scalar Expressions" section of the Jakarta Persistence specification:

spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved
spec/src/main/asciidoc/query-language.asciidoc Outdated Show resolved Hide resolved
spec/src/antlr/JDQL.g4 Show resolved Hide resolved
spec/src/antlr/JDQL.g4 Outdated Show resolved Hide resolved
spec/src/antlr/JDQL.g4 Outdated Show resolved Hide resolved
Copy link
Contributor

@njr-11 njr-11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm approving the pull, but we should consider if Contains was still useful for String attributes. The other option here would be to remove only the part that says it applies to collections.
Also, I didn't see where the removed keywords are added to the reserved list (in case there is a need to bring them back in the future), so we will need to be sure to cover that separately.

@gavinking
Copy link
Contributor Author

I'm approving the pull, but we should consider if Contains was still useful for String attributes. The other option here would be to remove only the part that says it applies to collections.

I wondered that, but then figured that since it's just a variation of Like that it wasn't really that useful. But I can put it back if necessary.

Also, I didn't see where the removed keywords are added to the reserved list (in case there is a need to bring them back in the future), so we will need to be sure to cover that separately.

You mean Contains and Empty? You want to add a new list of "Keywords Reserved for Future Use"?

@gavinking
Copy link
Contributor Author

To be specific: findByNameContains("hello%world") is the same as findByNameLike("%hello%world%").

@njr-11
Copy link
Contributor

njr-11 commented Mar 16, 2024

To be specific: findByNameContains("hello%world") is the same as findByNameLike("%hello%world%").

It is, but it requires the repository user to supply the % on their parameter, which might not be very natural to their usage, and they might not even like to know about wildcard characters. In your particular example, that user wouldn't care because they were already using a % in the middle of their pattern. But if they only wanted a single word or part of a word, they might not want to bother with wildcard characters on the ends of it.

@njr-11
Copy link
Contributor

njr-11 commented Mar 16, 2024

You mean Contains and Empty? You want to add a new list of "Keywords Reserved for Future Use"?

I don't think we need a new section. There is one in module-info here that can be used:

 * <h3>Reserved for Future Use</h3>

The important part of this is notifying the user to avoid them so that we would have the freedom to add them back if the need arises.

@gavinking
Copy link
Contributor Author

It is, but it requires the repository user to supply the % on their parameter, which might not be very natural to their usage, and they might not even like to know about wildcard characters.

So if you want it back just say the word....

@gavinking
Copy link
Contributor Author

You mean Contains and Empty? You want to add a new list of "Keywords Reserved for Future Use"?

I don't think we need a new section. There is one in module-info here that can be used:

 * <h3>Reserved for Future Use</h3>

Ugh. It gives me the heezy-jeebys when something is only mentioned in that module-info.java.

@gavinking gavinking force-pushed the jdql branch 2 times, most recently from 1856752 to 48bea10 Compare March 16, 2024 15:42
@gavinking
Copy link
Contributor Author

gavinking commented Mar 16, 2024

Well, see 7805071.

- bring Contains back to life (but only from Strings)
- add Empty to reserved words
@otaviojava
Copy link
Contributor

@gavinking could you fix the conflict?

@gavinking
Copy link
Contributor Author

@gavinking could you fix the conflict?

Done.

@otaviojava otaviojava merged commit 21104da into jakartaee:main Mar 17, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants